package com.diqye.engine;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.diqye.db.model.XModel;
import com.diqye.engine.interceptor.Interceptor;
import com.diqye.engine.render.JsonRender;
import com.diqye.engine.render.NullRender;
import com.diqye.templet.util.Strings;

/**
 * 方法 到  控制 映射
 * @author qinzl
 *
 */
public class RouteActions  {

	private Map<String, Route> dick = new HashMap<String, Route>();
	private static RouteActions me;
	public Interceptor head;
	private Logger log = Logger.getLogger(getClass());
	/**
	 *单例模式
	 */
	private RouteActions(){}
	public static RouteActions me(){
		if(me == null){
			me=new RouteActions();
		}
		return me;
	}
	
	/**
	 * action=Class_method
	 * @param controller
	 * @return
	 */
	public RouteActions add(Class<?extends Controller> controller){
		Method[] methods = controller.getMethods();
		for (int i = 0; i < methods.length; i++) {
			Method m = methods[i];
			if(m.getParameterTypes().length == 0){
				
				add(controller,m.getName());
			}
		}
		return this;
	}
	public RouteActions add(Class<?extends Controller> controller,String method){
		return add(controller.getSimpleName()+"_"+method,controller,method);
	}
	public RouteActions add(String action, Class<?extends Controller> controller,String method){
		if(dick.containsKey(action)){
			throw new RuntimeException(Strings.format("已存在的方法:{0}",action));
		}
		Route route = new Route();
		route.controller = controller;
		route.method = method;
		dick.put(action, route);
		return this;
	}
	
	/**
	 * 执行controller
	 * @param req request
	 * @param resp response
	 * @param action 应用唯一动作标识符
	 * @param model  对应传送的JSON
	 */
	public void invokConroller(HttpServletRequest req, HttpServletResponse resp,String action,XModel model){
		Controller controller = null;
		JsonRender render;
		Interceptor head = Constant.interceptors.head; //初始化拦截器
		if(!dick.containsKey(action)){//不存在的action 返回404页面
			if(Constant.jsonFileSupport){//如果是开发者模式 可使用假数据
				File f = new File(req.getSession().getServletContext().getRealPath("/")+"/data/"+action+".json");
				log.debug("加载文件"+f.getAbsolutePath());
				if(f.exists()){
					try {
						render = new JsonRender(FileUtils.readFileToString(f, Constant.encoding));
						render.cache=true;
						render.setContext(req, resp).render();
					} catch (IOException e) {
						e.printStackTrace();
					}
					return;
				}
			}
			new JsonRender(Constant.err404()).setContext(req, resp).render();
			return;
		}
		
		//获取Class
		Route route = dick.get(action);
		log.debug("\n-------路由----\n"+route.controller+"\n"+route.method+"\n--------------\n");
		Class<?extends Controller> controllerClass = route.controller;
		try {
			controller = controllerClass.newInstance();
			controller.setReqModel(model);
			controller.setRequest(req);
			controller.setResponse(resp);
	
			//执行拦截器
			head.intercept(action,controller,controllerClass.getMethod(route.method));
			//渲染页面
			if(controller.render == null){
				new NullRender().setContext(req, resp).render();
			}else{
				controller.render.setContext(req, resp);
				controller.render.render();
			}
		}catch (Exception e){
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			log.error(sw);
			new JsonRender(Constant.err500()).setContext(req, resp).render();
			throw new RuntimeException(e);
		}
		
	}
		
	
	
	public static class Route{
		public Class<?extends Controller> controller;
		public String method;
	}

}
